<template>
  <div>11111</div>
</template>

<script>
export default {
  data() {
    return {
      /*
      A     B
      J C D E
        F G H
            I
      */
      data: [],
    };
  },
  mounted() {
    let nodes = [
      [
        { id: "A", rank: -3 },
        { id: "B", rank: -3 },
      ],
      [
        { id: "J", rank: -2 },
        { id: "C", rank: -2 },
        { id: "D", rank: -2 },
        { id: "E", rank: -2 },
      ],
      [
        { id: "F", rank: -1 },
        { id: "G", rank: -1 },
        { id: "H", rank: -1 },
      ],
      [{ id: "I", rank: 0 }],
    ];
    let sides = [
      { id: "s1", from: "A", to: "C" },
      { id: "s2", from: "A", to: "D" },
      { id: "s1-1", from: "A", to: "J" },
      { id: "s3", from: "B", to: "E" },
      { id: "s4", from: "C", to: "F" },
      { id: "s5", from: "D", to: "G" },
      { id: "s6", from: "E", to: "H" },
      { id: "s7", from: "H", to: "I" },
    ];
    let getParentIds = this.getParentIdsFunc(sides);
    console.log(this.straighten(nodes, getParentIds));
  },
  methods: {
    getParentIdsFunc(sides) {
      let idMaps = sides.reduce((obj, d) => {
        if (!obj[d.from]) obj[d.from] = [];
        if (!obj[d.to]) obj[d.to] = [];
        obj[d.to].push(d.from);
        return obj;
      }, {});
      return (id) => {
        return idMaps[id];
      };
    },
    straighten(nodes, getParentIds) {
      let len = nodes.length;
      let maxOrder = nodes.reduce((m, n) => (m > n.length ? m : n.length), 0);
      console.log(maxOrder);
      while (len && len--) {
        if (nodes[len].length < maxOrder) {
          nodes[len] = this.expandArr(nodes[len], maxOrder);
        }
        let curRankNodes = nodes[len];
        curRankNodes.forEach((node, cIndex) => {
          if (!node) return;
          let pIds = getParentIds(node.id);
          let parentIndexArr = [];
          if (len > 0) {
            nodes[len - 1].forEach((rnode, pIndex) => {
              if (pIds.includes(rnode.id)) {
                parentIndexArr.push(pIndex);
              }
            });
          }

          let parentMiddleIndex =
            parentIndexArr[Math.floor(parentIndexArr.length / 2)];
          if (parentMiddleIndex != cIndex) {
            // 调整node和parent到相同的位置
            let tmp = curRankNodes[cIndex];
            if (!curRankNodes[parentMiddleIndex]) {
              curRankNodes[parentMiddleIndex] = tmp;
              curRankNodes[cIndex] = null;
            }
          }
        });
      }

      return nodes;
    },
    expandArr(arr, maxOrder) {
      return arr.concat(new Array(maxOrder - arr.length).fill(null));
    },
  },
};
</script>